#include<bits/stdc++.h>
#define REP(i,a,b,c) for(int i=a;i<=b;i+=c)
using namespace std;
const int N=1e5+5,P=1e6+5;
bool vis[N];
int T,n,m,L,ans[N],sum,pre[P],tot,ans2;
double dis[N],V,d[N],v[N],a[N],p[N];
struct Node{
    int l,r;
}node[N];
vector<int>g[N];
double solve_distance(double vx,double ax){
    return (V*V-vx*vx)/(2*ax);
}
void dfs(int x){
    if(!g[x].size()){
        ans2++;return;
    }
    for(auto y:g[x])
        if(!vis[y])vis[y]=1,dfs(y);
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    cin>>T;
    while(T--){sum=ans2=0;
        cin>>n>>m>>L>>V;
        REP(i,1,n,1){
            cin>>d[i]>>v[i]>>a[i];ans[i]=-1;
            if(a[i]!=0)dis[i]=solve_distance(v[i],a[i]);
            else  ans[i]=(v[i]>V?1:0),sum+=ans[i];
        }
        REP(i,1,m,1)  cin>>p[i],pre[(int)p[i]]=1;
        REP(i,1,P-5,1)pre[i]+=pre[i-1];
        REP(i,1,n,1){
            if(ans[i]==-1){
                if(pre[(int)floor(dis[i]+d[i])]-pre[(int)d[i]]>=1)
                    ans[i]=1;
                else ans[i]=0;sum+=ans[i];
            }
        }
        REP(i,1,n,1){
            if(ans[i]==1){
                if(a[i]==0){
                    node[++tot]={lower_bound(p+1,p+m+1,(int)d[i])-p,m};
                }else if(a[i]<0){
                    int r=lower_bound(p+1,p+m+1,(int)floor(dis[i]+d[i]))-p-1;
                    int l=lower_bound(p+1,p+m+1,(int)d[i])-p;node[++tot]={l,r};
                }else{
                    node[++tot]={upper_bound(p+1,p+m+1,(int)floor(dis[i]+d[i]))-p,m};
                }
            }
        }
        for(int i=1;i<=tot;i++){
            for(int j=1;j<=tot;j++){
                if(i==j)continue;
                if(node[i].l>=node[j].l&&node[i].r<=node[j].r)
                    g[j].push_back(i);
            }
        }
        REP(i,1,tot,1)
            if(!vis[i])vis[i]=1,dfs(i);
        REP(i,1,tot,1)g[i].clear(),vis[i]=0;
        memset(pre,0,sizeof(pre));
        cout<<sum<<" "<<m-ans2<<"\n";
    }return 0;
}
